import "../../lib/ramda.js";
import Utils from "../../lib/utils.js";
import Ux from "./ux.js";

const Consts = {
    FPS:20,
}

class _State {
    constructor() {
        this.ai_params = new Map([
            ["step-ms-max", 2000],
        ])
        this.reset()
    }
    reset() {
        this.game_state = 0
        this.ai_in_think = false
        this.ai_status = ""
    }
}
const State = new _State()

const AiManager = (()=>{
    const me = {}
    const _observers = []
    function make(){
        const worker = new Worker("./ai-engine.js", {type: "module"})
        worker.onmessage = (e)=>{
            const msg = e.data
            _observers.forEach(R.applyTo(msg))
        }
        worker.onerror = (e)=>{
            console.log(`AI-Error(${e.filename}[${e.lineno}]): ${e.message}`, e)
            State.ai_in_think = false
            State.ai_player = [false, false]
        }
        return worker
    }
    let _worker = make()
    me.listen = (f)=>{
        _observers.push(f)
        return me
    }
    me.send  = (...tokens)=>{
        const text = R.map(String, tokens).join(' ')
        _worker.postMessage(text)
        return me
    }
    me.restart = ()=>{
        _worker.postMessage("reset")
        return me
    }
    return me
})()

;(() => {
    const game_state = State.game_state
    const io = {
        ai_in_think(){
            return State.ai_in_think
        },
        ai_status(){
            return State.ai_status
        },
        ai_param(name){
            return State.ai_params.get(name)
        },
        ai_param_set(name, val){
            if (State.ai_params.has(name)) {
                AiManager.send(`set-${name}`, val)
                State.ai_params.set(name, val)
            }
            return this
        },
        on_cmd_reset(){
            State.reset()
            AiManager.restart()
            console.clear()
            return this
        },
    }

    const AiMessage = {}
    AiMessage["ready"] = ()=>{
        for (const kv of State.ai_params.entries()) {
            AiManager.send(`set-${kv[0]}`, kv[1])
        }
        AiManager.send("valuation", "")
    }
    AiMessage["step"] = (a,b)=>{
        State.ai_in_think = false
    }
    AiMessage["status"] = (...a)=>{
        State.ai_status = a.join(' ')
    }
    AiMessage["ok"] = (...a)=>{
        console.log("ok", ...a)
    }
    AiManager.listen((msg)=>{
        const tokens = msg.split(' ')
        if (tokens.length > 0) {
            const head = tokens[0]
            if (AiMessage.hasOwnProperty(head)) {
                AiMessage[head](...(tokens.slice(1)))
            } else {
                console.log("[Unknown-Message]", msg)
            }
        }
    })

    const on_frame = ()=>{
        if (State.ai_in_think) {return}
    }
    Ux.init(io)
    Utils.Clock.frame_watch(Ux.on_frame).frame_watch(on_frame).start(Consts.FPS)
})()
